package com.itic.appbase.applications.sys.user.controller;

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.itic.appbase.applications.sys.common.service.InnerCommonService;
import com.itic.appbase.applications.sys.org.persistence.model.Org;
import com.itic.appbase.applications.sys.relation.persistence.model.UserRole;
import com.itic.appbase.applications.sys.relation.service.UserRoleService;
import com.itic.appbase.applications.sys.resource.persistence.model.Resource;
import com.itic.appbase.applications.sys.role.persistence.model.Role;
import com.itic.appbase.applications.sys.user.persistence.model.SysUser;
import com.itic.appbase.applications.sys.user.persistence.model.SysUserExample;
import com.itic.appbase.applications.sys.user.persistence.model.SysUserExample.Criteria;
import com.itic.appbase.applications.sys.user.service.SysUserService;
import com.itic.appbase.applications.sys.user.vo.SysUserVo;
import com.itic.appbase.framework.common.constants.DBConst;
import com.itic.appbase.framework.common.constants.IticConst;
import com.itic.appbase.framework.common.constants.ResponseCode;
import com.itic.appbase.framework.common.controller.BaseController;
import com.itic.appbase.framework.exception.definition.ParameterErrorException;
import com.itic.appbase.framework.utils.IdGen;
import com.itic.appbase.framework.utils.MD5Helper;
import com.itic.appbase.framework.utils.StringHelper;
import com.itic.appbase.framework.utils.ValueHelper;

/**
 * 用户管理
 * <p>Company: itic</p>
 * 
 * @author: xujing
 * @date: 2015年6月1日 上午9:50:11
 * @version: V1.0
 */
@Controller
@RequestMapping(value = "/sys/user")
public class SysUserController
        extends BaseController {
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private InnerCommonService innerCommonService;

    @Autowired
    private UserRoleService userRoleService;

    private static final String RESET_PWD = "123456";
    private static final String MODEL_SYS_USER = "sysUser";

    private static final Map<String, String> codeMap = new HashMap<String, String>();

    static {
        codeMap.put("type", "T_DM_USER_TYPE");
        codeMap.put("isUsable", "T_DM_USER_ISUSABLE");
        codeMap.put("gender", "T_DM_USER_GENDER");
    }

    // 过滤返回属性黑名单
    private static String[] ignoreProperties = new String[] { "createUser", "isEffective", "createTime", "updateTime",
            "orgCode", "password", "gender", "tel", "mobile", "email", "orderNo", "type" };

    /**
     * 用户管理主页面
     * 
     * @param request
     * @param response
     * @return String
     */
    @RequestMapping(value = "/init")
    public String init() {
        return "sys/user/userMain";
    }

    /**
     * 用户管理右侧列表页面
     * 
     * @param request
     * @param model
     * @return String
     */
    @RequestMapping(value = "/initUser")
    public String initUser() {
        return "sys/user/userList";
    }

    /**
     * 新建页面
     * 
     * @param request
     * @param model
     * @return
     */
    @RequestMapping(value = "/initAdd")
    public String initAdd() {
        return "sys/user/userAdd";
    }

    /**
     * 编辑页面
     * 
     * @param id 用户id
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/initEdit")
    public String initEdit(String id, Model model) {
        if (StringHelper.isNotBlank(id)) {
            SysUser userRecord = sysUserService.get(id);
            model.addAttribute(MODEL_SYS_USER, iticJsonMapper.toJson(userRecord));
        } else {
            throw new ParameterErrorException();
        }

        return "sys/user/userEdit";
    }

    /**
     * 用户查询列表
     * 
     * @param request
     * @param response
     * @param sysUser 用户信息
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IntrospectionException
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Map<String, Object> getUserList(HttpServletRequest request, SysUser sysUser) {
        Map<String, Object> resultMap = new HashMap<String, Object>();

        // 封装查询条件
        SysUserExample example = new SysUserExample();
        example = this.handlePageQuery(request, example); // 封装分页参数
        example.setOrderByClause("org asc, order_no asc");

        Criteria criteria = example.createCriteria().andIsEffectiveEqualTo(DBConst.TRUE);

        if (null != sysUser) {
            if (StringHelper.isNotBlank(sysUser.getUsername())) {
                criteria.andUsernameLike("%" + sysUser.getUsername() + "%");
            }

            if (StringHelper.isNotBlank(sysUser.getRealname())) {
                criteria.andRealnameLike("%" + sysUser.getRealname() + "%");
            }

            if (StringHelper.isNotBlank(sysUser.getIsUsable())) {
                criteria.andIsUsableEqualTo(sysUser.getIsUsable());
            }

            if (StringHelper.isNotBlank(sysUser.getOrg())) {
                criteria.andOrgEqualTo(sysUser.getOrg());
            }
        }

        Integer total = sysUserService.count(example);
        List<SysUser> userList = sysUserService.list(example);
        for (SysUser user : userList) {
            // 组织机构名称
            Org org = innerCommonService.getOrgByCode(user.getOrg());
            user.setOrg(null != org && StringHelper.isNotBlank(org.getName()) ? org.getName() : "");
            // 代码表转换
            user = (SysUser) innerCommonService.getNameByCode(user, codeMap);
        }

        List<Map<String, Object>> resultList = ValueHelper.tranList2MapList(userList, ignoreProperties);

        resultMap.put(IticConst.TOTAL_RECORDS, total); // 总数，显示总数量
        resultMap.put(IticConst.DISPLAY_RECORDS, total); // 显示display中的总数量
        resultMap.put(IticConst.RESULT, ResponseCode.SUCCESS.getCode()); // 返回结果
        resultMap.put(IticConst.DATA, resultList); // 返回值
        return resultMap;
    }

    /**
     * 保存用户(角色)信息
     * 
     * @param request
     * @param sysUser 用户信息
     * @param roleIds 角色ids
     * @return
     */
    @RequestMapping(value = "/add")
    @ResponseBody
    public Map<String, String> add(SysUser sysUser, String roleIds) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (null != sysUser) {
            // 用户信息
            sysUser.setId(IdGen.uuid());
            sysUser.setPassword(MD5Helper.md5DoubleSalt(RESET_PWD, sysUser.getUsername()));

            List<UserRole> roleList = new ArrayList<UserRole>();
            // 用户角色
            if (StringHelper.isNotBlank(roleIds)) {
                String[] roleArray = roleIds.split(",");
                for (String roleId : roleArray) {
                    UserRole urTemp = new UserRole();

                    urTemp.setUserId(sysUser.getId());
                    urTemp.setRoleId(roleId);
                    roleList.add(urTemp);
                }
            }
            result = sysUserService.addUser(sysUser, roleList);
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }
        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

    /**
     * 编辑用户信息
     * 
     * @param request
     * @param sysUser 用户信息
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/edit")
    @ResponseBody
    public Map<String, String> edit(SysUser sysUser) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (null != sysUser && StringHelper.isNotBlank(sysUser.getId())) {
            result = sysUserService.edit(sysUser);
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }

        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

    /**
     * 删除用户(角色)信息
     * 
     * @param request
     * @param ids 用户ids
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/delete")
    @ResponseBody
    public Map<String, String> deleteUser(String ids) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (StringHelper.isNotBlank(ids)) {
            SysUserExample example = new SysUserExample();
            List<String> userIdList = Arrays.asList(ids.split(","));
            example.createCriteria().andIdIn(userIdList);
            SysUser sysUser = new SysUser();
            sysUser.setUpdateTime(new Date());
            sysUser.setIsEffective(DBConst.FALSE);
            result = sysUserService.deleteUser(sysUser, example, userIdList);
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }

        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

    /**
     * 查看用户(角色、资源)信息
     * 
     * @param id 用户id
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/initView")
    public String initView(String id, Model model) {
        if (StringHelper.isNotBlank(id)) {
            // 用户信息
            SysUser userRecord = sysUserService.get(id);
            if (null != userRecord) {
                // 用户拥有的角色名称
                List<Role> userOwnRolers = userRoleService.getUserOwnRolers(id);
                StringBuilder rolersName = new StringBuilder();
                for (Role role : userOwnRolers) {
                    rolersName.append(role.getName());
                    rolersName.append("   ");
                }

                // 用户拥有的资源信息
                List<Resource> resourceList = innerCommonService.getResourceByUserId(id);

                // 代码表转名称
                userRecord = (SysUser) innerCommonService.getNameByCode(userRecord, codeMap);

                // user转vo
                SysUserVo userVo = new SysUserVo();
                ValueHelper.model2vo(userRecord, userVo);

                // 组织机构名称
                Org userOrg = innerCommonService.getOrgByCode(userRecord.getOrg());
                userVo.setOrgName(null != userOrg ? userOrg.getName() : "");
                userVo.setRoleName(rolersName.toString().trim());

                model.addAttribute(MODEL_SYS_USER, userVo);
                model.addAttribute("resourceList", iticJsonMapper.toJson(resourceList));

            }

        } else {
            throw new ParameterErrorException();
        }
        return "sys/user/userView";
    }

    /**
     * 跳转到角色分配页面
     * 
     * @param id 用户id
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/initRoleAssign")
    public String initRoleAssign(String id, Model model) {
        if (StringHelper.isNotBlank(id)) {
            // 用户信息
            SysUser userRecord = sysUserService.get(id);
            // 用户已分配的角色信息
            List<Role> assignRolers = userRoleService.getUserOwnRolers(id);
            // 用户未分配的角色信息
            List<Role> unAssingRolers = userRoleService.getUserUnOwnRolers(id);

            model.addAttribute(MODEL_SYS_USER, userRecord);
            model.addAttribute("assignRolers", iticJsonMapper.toJson(assignRolers));
            model.addAttribute("unAssignRolers", iticJsonMapper.toJson(unAssingRolers));
        } else {
            throw new ParameterErrorException();
        }
        return "sys/user/userRoleAssign";
    }

    /**
     * 用户角色分配(授权/取消授权)
     * 
     * @param userId 用户id
     * @param roleIds 角色ids
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/roleAssign")
    @ResponseBody
    public Map<String, String> roleAssign(String userId, String roleIds) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (StringHelper.isNotBlank(userId)) {
            // 角色分配
            if (StringHelper.isNotBlank(roleIds)) {
                String[] roleArray = roleIds.split(",");
                List<UserRole> userRoleList = new ArrayList<UserRole>();
                for (String roleId : roleArray) {
                    UserRole urTemp = new UserRole();

                    urTemp.setUserId(userId);
                    urTemp.setRoleId(roleId);
                    userRoleList.add(urTemp);
                }
                result = sysUserService.roleAssign(userId, userRoleList);
            } else {
                // 根据userId删除用户角色关系
                result = userRoleService.deleteRoleByUserId(userId);
            }
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }
        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

    /**
     * 重置密码
     * 
     * @param ids
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/resetPwd")
    @ResponseBody
    public Map<String, String> resetPwd(String ids) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (StringHelper.isNotBlank(ids)) {
            SysUserExample example = new SysUserExample();
            example.createCriteria().andIdIn(Arrays.asList(ids.split(",")));
            List<SysUser> userList = sysUserService.list(example);
            result = sysUserService.resetPwd(RESET_PWD, userList);
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }

        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

    /**
     * 判断用户名是否可用
     * 
     * @param user
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/checkUsernameExist")
    @ResponseBody
    public Map<String, String> checkUsernameExist(SysUser user) {
        Map<String, String> resultMap = new HashMap<String, String>();
        String result = ResponseCode.SERVER_ERROR.getCode();

        if (null != user && StringHelper.isNotBlank(user.getUsername())) {
            SysUserExample example = new SysUserExample();
            example.createCriteria().andUsernameEqualTo(user.getUsername());
            List<SysUser> userList = sysUserService.list(example);
            result = userList != null && !userList.isEmpty() ? ResponseCode.EXIST.getCode() : ResponseCode.SUCCESS
                    .getCode();
        } else {
            result = ResponseCode.PARAM_INVALID.getCode();
        }
        resultMap.put(IticConst.RESULT, result);
        return resultMap;
    }

}